// Prevents additional console window on Windows in release, DO NOT REMOVE!!
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]

use tauri::{Manager, Window, AppHandle, Emitter};
use tauri_plugin_global_shortcut::{Shortcut, GlobalShortcutExt};
use std::fs;

// 设置窗口透明度
#[tauri::command]
async fn set_window_opacity(window: Window, opacity: f64) -> Result<(), String> {
    println!("[DEBUG] set_window_opacity called with opacity: {}", opacity);
    
    // 限制透明度范围在 0.0 到 1.0 之间
    let clamped_opacity = opacity.max(0.0).min(1.0);
    println!("[DEBUG] Clamped opacity: {}", clamped_opacity);
    
    // 使用 Tauri 2.x 的正确 API 设置窗口透明度
    #[cfg(target_os = "windows")]
    {
        use windows::Win32::Foundation::HWND;
        use windows::Win32::UI::WindowsAndMessaging::{SetWindowLongPtrW, SetLayeredWindowAttributes, GWL_EXSTYLE, WS_EX_LAYERED, LWA_ALPHA, GetWindowLongPtrW};
        
        println!("[DEBUG] Getting window handle...");
        let hwnd = window.hwnd().map_err(|e| {
            let error_msg = format!("Failed to get window handle: {}", e);
            println!("[ERROR] {}", error_msg);
            error_msg
        })?;
        let hwnd = HWND(hwnd.0);
        println!("[DEBUG] Window handle obtained: {:?}", hwnd);
        
        unsafe {
            // 获取当前窗口样式
            let current_style = GetWindowLongPtrW(hwnd, GWL_EXSTYLE);
            println!("[DEBUG] Current window extended style: 0x{:x}", current_style);
            
            // 设置窗口为分层窗口
            let new_style = current_style | (WS_EX_LAYERED.0 as isize);
            println!("[DEBUG] Setting new extended style: 0x{:x}", new_style);
            
            let ex_style = SetWindowLongPtrW(hwnd, GWL_EXSTYLE, new_style);
            println!("[DEBUG] SetWindowLongPtrW result: 0x{:x}", ex_style);
            
            // 设置透明度
            let alpha = (clamped_opacity * 255.0) as u8;
            println!("[DEBUG] Setting alpha value: {} ({}%)", alpha, (alpha as f64 / 255.0 * 100.0) as u32);
            
            let result = SetLayeredWindowAttributes(hwnd, windows::Win32::Foundation::COLORREF(0), alpha, LWA_ALPHA);
            match result {
                Ok(_) => {
                    println!("[DEBUG] SetLayeredWindowAttributes succeeded");
                },
                Err(e) => {
                    let error_msg = format!("SetLayeredWindowAttributes failed: {:?}", e);
                    println!("[ERROR] {}", error_msg);
                    return Err(error_msg);
                }
            }
        }
    }
    
    #[cfg(not(target_os = "windows"))]
    {
        // 对于非 Windows 平台，尝试使用 Tauri 的内置方法
        // 注意：某些平台可能不支持窗口透明度
        return Err("Window opacity is only supported on Windows".to_string());
    }
    
    // 发送事件通知前端透明度已更改
    window.emit("opacity-changed", clamped_opacity).map_err(|e| e.to_string())?;
    Ok(())
}

// 设置窗口置顶
#[tauri::command]
async fn set_always_on_top(window: Window, always_on_top: bool) -> Result<(), String> {
    window.set_always_on_top(always_on_top).map_err(|e| e.to_string())
}

// 切换窗口可见性
#[tauri::command]
async fn toggle_window_visibility(window: Window) -> Result<(), String> {
    if window.is_visible().map_err(|e| e.to_string())? {
        window.hide().map_err(|e| e.to_string())
    } else {
        window.show().map_err(|e| e.to_string())
    }
}

// 设置窗口位置
#[tauri::command]
async fn set_window_position(window: Window, x: i32, y: i32) -> Result<(), String> {
    use tauri::Position;
    window.set_position(Position::Physical(tauri::PhysicalPosition { x, y }))
        .map_err(|e| e.to_string())
}

// 设置窗口大小
#[tauri::command]
async fn set_window_size(window: Window, width: u32, height: u32) -> Result<(), String> {
    use tauri::Size;
    window.set_size(Size::Physical(tauri::PhysicalSize { width, height }))
        .map_err(|e| e.to_string())
}

// 获取窗口信息
#[tauri::command]
async fn get_window_info(window: Window) -> Result<serde_json::Value, String> {
    let position = window.outer_position().map_err(|e| e.to_string())?;
    let size = window.outer_size().map_err(|e| e.to_string())?;
    let is_visible = window.is_visible().map_err(|e| e.to_string())?;
    
    Ok(serde_json::json!({
        "position": {
            "x": position.x,
            "y": position.y
        },
        "size": {
            "width": size.width,
            "height": size.height
        },
        "isVisible": is_visible
    }))
}

// 注册全局快捷键
#[tauri::command]
async fn register_global_shortcut(app: AppHandle, shortcut: String, action: String) -> Result<(), String> {
    let shortcut_obj = shortcut.parse::<Shortcut>().map_err(|e| e.to_string())?;
    
    // 在Tauri 2.x中，全局快捷键的事件处理需要通过不同的方式实现
    // 这里先注册快捷键，事件处理通过前端监听实现
    app.global_shortcut().register(shortcut_obj).map_err(|e| e.to_string())?;
    
    // 发送事件到前端，告知快捷键已注册
    if let Some(window) = app.get_webview_window("main") {
        let _ = window.emit("shortcut-registered", serde_json::json!({
            "shortcut": shortcut,
            "action": action
        }));
    }
    
    Ok(())
}

// 取消注册全局快捷键
#[tauri::command]
async fn unregister_global_shortcut(app: AppHandle, shortcut: String) -> Result<(), String> {
    let shortcut_obj = shortcut.parse::<Shortcut>().map_err(|e| e.to_string())?;
    app.global_shortcut().unregister(shortcut_obj).map_err(|e| e.to_string())?;
    Ok(())
}

// 保存配置到本地文件
#[tauri::command]
async fn save_config(app: AppHandle, config: serde_json::Value) -> Result<(), String> {
    let app_dir = app.path().app_config_dir().map_err(|e| e.to_string())?;
    fs::create_dir_all(&app_dir).map_err(|e| e.to_string())?;
    
    let config_path = app_dir.join("config.json");
    let config_str = serde_json::to_string_pretty(&config).map_err(|e| e.to_string())?;
    
    fs::write(config_path, config_str).map_err(|e| e.to_string())?;
    Ok(())
}

// 加载本地配置文件
#[tauri::command]
async fn load_config(app: AppHandle) -> Result<serde_json::Value, String> {
    let app_dir = app.path().app_config_dir().map_err(|e| e.to_string())?;
    let config_path = app_dir.join("config.json");
    
    if config_path.exists() {
        let config_str = fs::read_to_string(config_path).map_err(|e| e.to_string())?;
        let config: serde_json::Value = serde_json::from_str(&config_str).map_err(|e| e.to_string())?;
        Ok(config)
    } else {
        // 返回默认配置
        Ok(serde_json::json!({
            "window": {
                "opacity": 0.9,
                "alwaysOnTop": false,
                "width": 1200,
                "height": 800
            },
            "shortcuts": {
                "toggleVisibility": "Ctrl+Shift+H",
                "increaseOpacity": "Ctrl+Shift+Up",
                "decreaseOpacity": "Ctrl+Shift+Down"
            },
            "behavior": {
                "hideOnStartup": false,
                "minimizeToTray": true,
                "autoHideDelay": 0
            }
        }))
    }
}

// 最小化窗口
#[tauri::command]
async fn minimize_window(window: Window) -> Result<(), String> {
    window.minimize().map_err(|e| e.to_string())
}

// 关闭窗口
#[tauri::command]
async fn close_window(window: Window) -> Result<(), String> {
    window.close().map_err(|e| e.to_string())
}

// 隐藏窗口
#[tauri::command]
async fn hide_window(window: Window) -> Result<(), String> {
    window.hide().map_err(|e| e.to_string())
}

// 显示窗口
#[tauri::command]
async fn show_window(window: Window) -> Result<(), String> {
    window.show().map_err(|e| e.to_string())
}

fn main() {
    tauri::Builder::default()
        // 移除tauri_plugin_window依赖，Tauri 2.x中窗口功能已内置
        .plugin(tauri_plugin_global_shortcut::Builder::new().build())
        .invoke_handler(tauri::generate_handler![
            set_window_opacity,
            set_always_on_top,
            toggle_window_visibility,
            set_window_position,
            set_window_size,
            get_window_info,
            register_global_shortcut,
            unregister_global_shortcut,
            save_config,
            load_config,
            minimize_window,
            close_window,
            hide_window,
            show_window
        ])
        .run(tauri::generate_context!())
        .expect("error while running tauri application");
}
